#ifndef _PROC_H_
#define _PROC_H_

#define PROCTAB_SIZE		1024
#define NICE2PRIO(x)		(20 - x)
#define PRIO2NICE(x)		(20 - x)
#define KERNEL_FILE_NAME	"RedMoon"

#include <types.h>
#include <List.h>
#include <Spinlock.h>

typedef enum {
	psRunning = 0,
	psReady,
	psSleeping,
	psStopped,
	psZombie
} ProcessState;

struct tms {
	dword tms_utime;
	dword tms_stime;
	dword tms_cutime;
	dword tms_cstime;
};

struct Process {
	// Processes list
	List list;
	// Process lock
	Spinlock lock;
	// Process ID
	pid_t pid;
	// Process state
	ProcessState state;
	// process flags
	dword flags;
	// Process name
	char name[256];
	// Parent process
	struct Process *parent;
	// childs count
	int childs;
	// Process times
	struct tms tms;
	dword starttime;
	// process priority
	int priority;
	int ticks;
	// Used when process wait for child
	int waitpid;
	// Used when process sleep
	long counter;
	// process exit code
	int exit_code;
	// saved cpu context
	struct CPUContext *ctx;
	struct CPUContext *old_ctx;
	int ctx_not_save;
	// kernel stack pointer
	void *kstack;
};

struct ProcessInfo {
	pid_t pid;
	char name[256];
	pid_t ppid;
	int nice;
	int state;
	struct tms tms;
};

class Proc {
public:
	static void Init();
	static Process *GetKernelProc();
	static Process *GetProc(pid_t);
	static void Add(Process *);
	static void Delete(Process *);
	static pid_t Spawn(Process *);
	static pid_t CreateThread(void *entry, char *name);
	static int Stat(ProcessInfo *);

	static void CreateCTX(Process *p, void *entry);

	static Process *proctab[PROCTAB_SIZE];
};

class Scheduler {
public:
	static void Yield();
	static void WakeUp(Process *p);
	static void SleepOn(List * wait);
	static int Sleep(dword ms);
	static void Schedule();

	static bool Initialized;
	static Process *Current;
	static Process *Next;
	static Spinlock Lock;
	static List ReadyList;	
};

#endif
